using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace Banshee.Base.Winforms.Controls
{
    public class MarkUpLable:Label
    {
        private static string startTag = "<b>";
        private static string endTag = "</b>";
        public MarkUpLable()
        {

        }
        public override string Text
        {
            get
            {
                return GetCleanText(base.Text);
            }
            set
            {
                base.Text = value;
            }
        }
        private String GetCleanText(String text)
        {
            if (text == null)
            {
                return null;
            }
            string cleanString = text.Replace(startTag, "");
            cleanString = cleanString.Replace(endTag, "");
            return cleanString;
        }

        private List<CharacterRange> GetCharacterRanges(string text)
        {
            int start = 0;
            List<CharacterRange> characterRanges = new List<CharacterRange>();
            int charsRemoved = 0;
            while (start < text.Length)
            {
                start = text.IndexOf(startTag, start);
                if (start >= 0)
                {
                    int end = text.IndexOf(endTag, start);
                    int ofs = start - charsRemoved;
                    int length = end - charsRemoved - startTag.Length - ofs;
                    characterRanges.Add(new CharacterRange(ofs, length));
                    start = end + startTag.Length;
                    charsRemoved += (startTag.Length + endTag.Length);
                }
                else
                {
                    break;
                }
            }
            return characterRanges;
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            //base.OnPaint(e);
            Graphics g = e.Graphics;
            Rectangle rect = ClientRectangle;
            g.FillRectangle(new SolidBrush(BackColor), rect);
            DrawTaggedString(g, base.Text, base.Font, new SolidBrush(ForeColor), Rectangle.Round(rect),new StringFormat());
            
        }
        private void DrawTaggedString(Graphics g, String text, Font font, Brush brush, RectangleF layoutRect, StringFormat stringFormat)
        {
            List<CharacterRange> characterRanges = GetCharacterRanges(text);
            // Now the ugly part. Because of Microsoft's bug that limits the array passed to SetMeasurableCharacterRanges
            // to 32 only. We loop on chunks of 32 elements each time.
            int offset = 0;
            int countLeft = characterRanges.Count;
            do
            {
                int count = Math.Min(countLeft, 32);
                List<CharacterRange> subRange = characterRanges.GetRange(offset, count);
                int ranges = subRange.Count;

                string cleanString = GetCleanText(text);
                stringFormat.SetMeasurableCharacterRanges(subRange.ToArray());
                // Measure all the regions - use the clean string now to get them
                Region[] stringRegions;
                stringRegions = g.MeasureCharacterRanges(cleanString, font, layoutRect, stringFormat);

                // Loop on all the ranges and draw a blue rectangle - this will mark the found string
                for (int i = 0; i < ranges; i++)
                {
                    RectangleF measureRect = stringRegions[i].GetBounds(g);
                    g.FillRectangle(Brushes.WhiteSmoke, Rectangle.Round(measureRect));
                }
                // Draw string to screen.
                g.DrawString(cleanString, font, brush, layoutRect, stringFormat);

                offset += count;
                countLeft -= count;

            } while (countLeft > 0);
        }
    }
}
